#include <iostream>
#include <thread>
#include <unistd.h>

#include "../common/Dispatcher.hpp"
#include "../client/Requester.hpp"
#include "../client/RpcCaller.hpp"

void cb(const Json::Value& result)
{
    ILOG("result: %d", result.asInt());
}


int main()
{
    rpc::client::Requester::ptr requester = std::make_shared<rpc::client::Requester>();
    rpc::client::RpcCaller::ptr rpc_caller = std::make_shared<rpc::client::RpcCaller>(requester);


    rpc::Dispatcher::ptr dispatcher = std::make_shared<rpc::Dispatcher>();
    auto callback = std::bind(&rpc::client::Requester::onResponse, requester.get(), 
        std::placeholders::_1, std::placeholders::_2);

    dispatcher->registerHandler<rpc::BaseMessage>(rpc::MSG_TYPE::RSP_RPC, callback);
    
    rpc::BaseClient::ptr client = rpc::ClientFactory::create("127.0.0.1", 8080);
    client->setMessageCallback(std::bind(&rpc::Dispatcher::onMessage, dispatcher.get(), std::placeholders::_1, std::placeholders::_2));
    client->connect();

    auto conn = client->connection();

    Json::Value params;
    params["num1"] = 44;
    params["num2"] = 33;
    Json::Value result;
    // 3.
    auto ret = rpc_caller->call(conn, "Add", params, cb);

    sleep(1);
    std::cout << "------" << std::endl;

    // 1. 
    // auto ret = rpc_caller->call(conn, "Add", params, result);
    // if (ret != false)
    // {
    //     ILOG("result: %d", result.asInt());
    // }

    // 2. 
    // rpc::client::RpcCaller::JsonAsyncResponse async_rsp;
    // auto ret = rpc_caller->call(conn, "Add", params, async_rsp);
    // if (ret != false)
    // {
    //     result = async_rsp.get();
    //     ILOG("result: %d", result.asInt());
    // }

    client->shutdown();
    return 0;
}


// void onRpcResponse(const rpc::BaseConnection::ptr & conn, const rpc::RpcResponse::ptr &msg)
// {
//     std::cout << "onRpcResponse" << std::endl;
//     std::string body = msg->serialize();
//     std::cout << body << std::endl;
// }

// void onTopicResponse(const rpc::BaseConnection::ptr & conn, const rpc::TopicResponse::ptr &msg)
// {
//     std::cout << "onTopicResponse" << std::endl;
//     std::string body = msg->serialize();
//     std::cout << body << std::endl;
// }

// int main()
// {
//     rpc::Dispatcher::ptr dispatcher = std::make_shared<rpc::Dispatcher>();

//     dispatcher->registerHandler<rpc::RpcResponse>(rpc::MSG_TYPE::RSP_RPC, onRpcResponse);
//     dispatcher->registerHandler<rpc::TopicResponse>(rpc::MSG_TYPE::RSP_TOPIC, onTopicResponse);
    
    
//     rpc::BaseClient::ptr client = rpc::ClientFactory::create("127.0.0.1", 8080);
//     client->setMessageCallback(std::bind(&rpc::Dispatcher::onMessage, dispatcher.get(), std::placeholders::_1, std::placeholders::_2));
//     client->connect();


//     rpc::RpcRequest::ptr req = rpc::MessageFactory::create<rpc::RpcRequest>();
//     req->setId(rpc::UUID::uuid());
//     req->setMsgType(rpc::MSG_TYPE::REQ_RPC);
//     req->setMethod("Add");

//     Json::Value param;
//     param["num1"] = 11;
//     param["num2"] = 22;
//     req->setParams(param);

//     client->send(req);
    
//     std::this_thread::sleep_for(std::chrono::minutes(100));
//     // std::this_thread::sleep_for(chrono());
//     client->shutdown();
//     return 0;
// }